package community.hospital.service.application.impl;

import community.hospital.common.CustomerException;
import community.hospital.common.R;
import community.hospital.convert.CommonConvert;
import community.hospital.convert.DepartmentConvert;
import community.hospital.entity.Department;
import community.hospital.entity.request.DepartmentRequest;
import community.hospital.entity.request.ListDepartmentRequest;
import community.hospital.entity.response.DepartmentOptionResponse;
import community.hospital.entity.response.DepartmentResponse;

import community.hospital.entity.response.OptionResp;
import community.hospital.service.application.DepartmentApplicationService;
import community.hospital.service.domain.DepartmentService;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static community.hospital.common.Constant.STATE_ENABLE;
import static community.hospital.enums.BusinessEnum.DEPT_NAME_REPEAT;

/**
 * @author yindingjie
 */
@Service
public class DepartmentApplicationServiceImpl implements DepartmentApplicationService {
    @Resource
    private DepartmentService departmentService;
    @Override
    public List<DepartmentResponse> listDepartment(ListDepartmentRequest request) {
        List<Department> departmentList = departmentService.listDepartment(request);
        List<DepartmentResponse> responseList = CommonConvert.convert(departmentList, DepartmentConvert.INSTANCE::convertToResp);
        //找出一级科室
         List<DepartmentResponse> parentResponseList =  responseList.stream()
                .filter(departmentResponse -> departmentResponse.getPid().equals(0L))
                .collect(Collectors.toList());
                //找出该一级科室对应的二级科室
         parentResponseList.forEach(departmentResponse -> {
            List<DepartmentResponse> childrenDepartmentList = departmentList.stream()
                    .filter(childerDepartment -> childerDepartment.getPid().equals(departmentResponse.getId()))
                    .map(DepartmentConvert.INSTANCE::convertToResp)
                    .collect(Collectors.toList());
                    departmentResponse.setChildren(childrenDepartmentList);
                });

        return parentResponseList;
    }

    @Override
    public Boolean addDepartment(DepartmentRequest request) {
        Department department = DepartmentConvert.INSTANCE.convertToDepartment(request);
        checkDeptNameRepeat(request.getDeptName());
        return departmentService.save(department);
    }

    @Override
    public Boolean updateDepartment(DepartmentRequest request) {
        Department department = DepartmentConvert.INSTANCE.convertToDepartment(request);
        checkDeptNameRepeat(department.getId(),request.getDeptName());
        return departmentService.updateById(department);
    }

    @Override
    public Boolean removeDepartment(List<Long> ids) {
        //ids中包含一级科室/二级科室，删除一级科室同时删除二级科室
        List<Department> departmentList =  departmentService.listDepartmentByIds(ids);
        List<Long> departmentIds = departmentList.stream().map(Department::getId).collect(Collectors.toList());
        return departmentService.removeBatchByIds(departmentIds);
    }

    @Override
    public DepartmentResponse queryById(Long departmentId) {
        Department department = departmentService.getById(departmentId);
        DepartmentResponse departmentResponse = DepartmentConvert.INSTANCE.convertToResp(department);
        return departmentResponse;
    }

    @Override
    public List<DepartmentOptionResponse> getDepartmentOption(Long hospitalId) {
        ListDepartmentRequest request = new ListDepartmentRequest();
        request.setState(STATE_ENABLE);
        request.setHospitalId(hospitalId);
        List<Department> departmentList = departmentService.listParentDepartment(request);
        List<DepartmentOptionResponse> responseList = CommonConvert.convert(departmentList, DepartmentConvert.INSTANCE::convertToDepartmentOptionRequest);
        return responseList;
    }

    @Override
    public Boolean updateStatus(DepartmentRequest request) {
        Department department = DepartmentConvert.INSTANCE.convertToDepartment(request);
        return departmentService.updateById(department);

    }

    @Override
    public List<Department> list1Department() {
        return departmentService.list1Department();

    }

    @Override
    public List<DepartmentResponse> listAllDepartment() {
        List<Department> departmentList = departmentService.list();
        return CommonConvert.convert(departmentList, DepartmentConvert.INSTANCE::convertToResp);

    }

    @Override
    public List<OptionResp> listByHospitalId(Long hospitalId) {
        List<Department> departmentList = departmentService.listByHospitalId(hospitalId);
        //1级科室
        List<OptionResp> optionRespList = departmentList
                .stream().filter(department -> department.getPid().equals(0L))
                .map(this::departmentToOptionResp)
                .collect(Collectors.toList());
        //递归找子科室
        getChildren(departmentList, optionRespList);
        return optionRespList;
    }

    private void getChildren(List<Department> departmentList,List<OptionResp> optionRespList){
        optionRespList.stream().forEach(optionResp -> {
            List<OptionResp> childrenList = departmentList.stream()
                    .filter(department -> department.getPid().equals(optionResp.getKey()))
                    .map(this::departmentToOptionResp).collect(Collectors.toList());
            optionResp.setChildren(childrenList);
            getChildren(departmentList,childrenList);
        });
    }
    private OptionResp departmentToOptionResp(Department department){
        OptionResp optionResp = new OptionResp();
        optionResp.setLabel(department.getDeptName());
        optionResp.setTitle(department.getDeptName());
        optionResp.setValue(department.getId());
        optionResp.setKey(department.getId());
        optionResp.setPid(department.getPid());
        return optionResp;
    }

    private void checkDeptNameRepeat(String deptName) {
        int count = departmentService.countByDeptName(deptName);
        if (count > 0) {
            throw new CustomerException(DEPT_NAME_REPEAT);
        }
    }
    private void checkDeptNameRepeat(Long id,String deptName){
        Department department = departmentService.getById(id);
        if (!department.getDeptName().equals(deptName)) {
            checkDeptNameRepeat(deptName);
        }
    }


}
